home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48_2 / h_piper_.src < prev    next >
Internet Message Format  |  1995-03-31  |  38KB

  1. Path: ecsgate!mcnc!gatech!prism!vapsppr
  2. From: vapsppr@prism.gatech.EDU (Paul Raines)
  3. Newsgroups: comp.sys.handhelds
  4. Subject: H. Piper! ver 2.0 (SOURCE CODE)
  5. Message-ID: <29881@hydra.gatech.EDU>
  6. Date: 26 May 91 16:23:39 GMT
  7. Organization: Georgia Institute of Technology
  8. Lines: 1042
  9.  
  10. The source code in Chipper for ver 2.0 of H. Piper! follows
  11. below.  There are some significant changes in some of the
  12. logic.  For people having problems with getting the ASC
  13. version to run, try compiling this program and using its
  14. output.
  15.  
  16. ;  H. Piper Game for the HP48SX
  17. ;  (c) Paul Raines
  18.  
  19. ;  Register usage:
  20. ;  V0:  Temporary data, may change during any call
  21. ;  V1:  Temporary data, may change during any call
  22. ;  V2:  Temporary data, may change during any call
  23. ;  V3:  Temporary data, may change during any call
  24. ;  V4:  Temporary data, may change during any call
  25. ;  V5:  Temporary data, may change during any call
  26. ;  V6:  Temporary data, may change during any call
  27. ;  V7:  Current Job Score (ones & tens)
  28. ;  V8:  Current Job Score (hundreds & up)
  29. ;  V9:  Current Box type
  30. ;  VA:  Box progression
  31. ;  VB:  Flow direction
  32. ;  VC:  Current Box pos
  33. ;  VD:  Paddle position
  34. ;  VE:  Speed Level
  35. ;  VF:  Flag register
  36.  
  37. ;  NOTE: Box position is stored in one register such that
  38. ;                        #34h
  39. ;                  y pos --^^--- x pos on grid
  40. ;
  41. ;        Two registers are used for the score in order to
  42. ;        have a decimal number greater than 255.
  43.  
  44. ; *************************
  45. ; START OF DEFINITIONS AREA
  46. ; *************************
  47.  
  48. F_UP    =   #00  ; direction definitions
  49. F_DOWN  =   #03
  50. F_RIGHT =   #06
  51. F_LEFT  =   #05
  52.  
  53. B_NE    =   #1D  ; pipe definitions
  54. B_SW    =   #15
  55. B_NW    =   #1E            ; NOTE THAT
  56. B_SE    =   #16            ;
  57. B_VERT  =   #01            ;    B_SE xor F_UP   and #07 = F_RIGHT
  58. B_HORZ  =   #02            ;    B_SW xor F_UP   and #07 = F_LEFT
  59. B_CROS  =   #03            ;    B_NE xor F_LEFT and #07 = F_UP
  60. B_ESTR  =   #07            ;    ...
  61. B_WSTR  =   #08            ;    ...
  62. B_NSTR  =   #09
  63. B_SSTR  =   #0A
  64.  
  65. ; Key definitions
  66. ;    ( 7 )  ->  #1    ( 8 )  ->  #2    ( 9 )  ->  #3    ( / )  ->  #C
  67. ;    ( 4 )  ->  #4    ( 5 )  ->  #5    ( 6 )  ->  #6    ( * )  ->  #D
  68. ;    ( 1 )  ->  #7    ( 2 )  ->  #8    ( 3 )  ->  #9    ( - )  ->  #E
  69. ;    ( 0 )  ->  #A    ( . )  ->  #0    ( _ )  ->  #B    ( + )  ->  #F
  70.  
  71. K_LEFT  =   #07
  72. K_RIGHT =   #08
  73. K_UP    =   #03
  74. K_DOWN  =   #06
  75. K_FAST  =   #0F
  76. K_PLACE =   #01
  77. K_UPLACE =  #04
  78.  
  79. TYPERATE =  #90   ; repeat rate for holding down key
  80.  
  81. ; ******************
  82. ; START OF CODE AREA
  83. ; ******************
  84.  
  85.             JP    FIRST
  86.  
  87. COPYRIGHT:  DA    'v2.0 Raines (c) 1991'
  88.  
  89. FIRST:      DB    #00, #FF            ; turnon extend mode
  90.             DB    #F3, #85            ; read incoming paused score and level
  91.             LD    VE, V2              ; starting level
  92.             SNE   V3, #1              ; if resuming paused game
  93.             JP    RESUME
  94.             LD    VE, #4E             ; starting level
  95.             LD    V0, 0               ; Zero out total score
  96.             LD    V1, 0               ;   "          "
  97. RESUME:     LD    I, TSCORE           ;  Set total score from flags
  98.             LD    [I], V1             ;  "        "
  99.             LD    VC, #FF             ; signal for random starting placement
  100.             LD    V0, 0
  101.             LD    V1, 0
  102.             LD    V2, 0
  103.             DB    #F2, #75            ; clear user flags
  104.  
  105. ; *** SETUP SCREEN, DATA AREA, AND REGISTERS FOR GAME PLAY ***
  106. START:      CLS
  107.             LD    V0, #0B             ; Fill grid array data
  108.             LD    V1, #00             ; area with unfilled
  109.             LD    V2, 0               ; unused grid sites
  110. CLEARGRID:  LD    I, BOXINFO          ;  "        "
  111.             ADD   I, V2               ;  "        "
  112.             LD    [I], V1             ;  "        "
  113.             ADD   V2, 2               ;  "        "
  114.             SE    V2, 120             ;  "        "
  115.             JP    CLEARGRID           ;  "        "
  116.             LD    V0, #00             ; Fill preview array data
  117.             LD    V2, 0               ; area with blank blocks
  118. CLEARPREV:  LD    I, PBOXINFO         ;  "        "
  119.             ADD   I, V2               ;  "        "
  120.             LD    [I], V1             ;  "        "
  121.             ADD   V2, 2               ;  "        "
  122.             SE    V2, 6               ;  "        "
  123.             JP    CLEARPREV           ;  "        "
  124.  
  125.             LD    I, TITLE            ; Draw title "H. Piper!"
  126.             LD    V0, 38
  127.             LD    V1, 57
  128.             LD    V3, 0
  129. DRAWTITLE:  ADD   I, V3
  130.             DRW   V0, V1, 5
  131.             LD    V3, 5
  132.             ADD   V0, 8
  133.             SE    V0, 70
  134.             JP    DRAWTITLE
  135.  
  136.             LD    I, HDSCORE          ; Draw score and level heading
  137.             LD    V0, 104
  138.             LD    V1, 2
  139.             DRW   V0, V1, 5
  140.             ADD   V0, 8
  141.             LD    V2, 5
  142.             ADD   I, V2
  143.             DRW   V0, V1, 5
  144.             LD    I, HDLEVEL
  145.             LD    V0, 104
  146.             LD    V1, 42
  147.             DRW   V0, V1, 5
  148.             ADD   V0, 8
  149.             LD    V2, 5
  150.             ADD   I, V2
  151.             DRW   V0, V1, 5
  152.  
  153.             LD    V1, VE              ; draw needed score
  154.             SHR   V1
  155.             LD    V0, 100
  156.             SUB   V0, V1                 ; determine needed score
  157.             LD    I, TEMP
  158.             LD    B, V0                  ; write BCD of needed score
  159.             LD    V2, [I]                ; read BCD in three parts
  160.             LD    V3, 90
  161.             LD    V4, 57
  162.             LD    F, V1                  ; point to sprite of tens digit
  163.             DRW   V3, V4, 5              ; draw it
  164.             ADD   V3, 5
  165.             LD    F, V2                  ; point to sprite of ones digit
  166.             DRW   V3, V4, 5              ; draw it
  167.  
  168.             LD    V0, VE              ; store the current level in memory
  169.             LD    I, LEVEL            ;   in case some uses FAST key
  170.             LD    [I], V0
  171.  
  172.             LD    I, HORZBOX          ; draw top border
  173.             LD    V0, 0
  174.             LD    V1, 0
  175. RDTOP:      DRW   V0, V1, 2
  176.             ADD   V0, 8
  177.             SE    V0, 96
  178.             JP    RDTOP
  179.  
  180.  
  181.  
  182.             LD    V4, 2
  183. RDPRV:      LD    I, PRV1BOX          ; Draw preview boxes grids
  184.             LD    V0, 0
  185.             DRW   V0, V4, 12
  186.             LD    I, PRV2BOX
  187.             LD    V0, 8
  188.             DRW   V0, V4, 12
  189.             ADD   V4, 12
  190.             SE    V4, 62
  191.             JP    RDPRV
  192.  
  193.             LD    V7, 0
  194. PREVAGAIN:  LD    V0, V7              ; favor corners for first 4 preview boxes
  195.             CALL  GETRANDBLK          ; randomly get five new
  196.             ADD   V7, 1               ;    preview boxes
  197.             SE    V7, 5
  198.             JP    PREVAGAIN
  199.  
  200.             LD    V1, 50              ; draw bottom border
  201.             LD    V0, 16
  202.             LD    I, FULLBOX
  203. RDBBDR:     DRW   V0, V1, 6
  204.             ADD   V0, 8
  205.             SE    V0, 96
  206.             JP    RDBBDR
  207.  
  208.             LD    V1, 0               ; Draw right border
  209.             LD    V0, 96
  210.             LD    I, RBORDER
  211. RDRBDR:     DRW   V0, V1, 2
  212.             ADD   V1, 2
  213.             SE    V1, 56
  214.             JP    RDRBDR
  215.  
  216.             LD    VD, #34             ; Draw initial paddles
  217.             CALL  DRAWBPADL
  218.             CALL  DRAWSPADL
  219.             CALL  DRAWCRSHR
  220.  
  221.             LD    V1, 2               ; Draw grid boxes
  222.             LD    I, GRID
  223. RDGRID1:    LD    V0, 16
  224. RDGRID2:    DRW   V0, V1, 8
  225.             ADD   V0, 8
  226.             SE    V0, 96
  227.             JP    RDGRID2
  228.             ADD   V1, 8
  229.             SE    V1, 50
  230.             JP    RDGRID1
  231.  
  232.             SNE   VC, #FF         ; get starting direction and box
  233.             JP    RANDSTART       ; if not first job, use last box
  234. NOTCORNER:  SNE   VB, #00            ;if last direction was down
  235.             LD    V3, #6             ;    make start direction up
  236.             SNE   VB, #03            ;if last direction was up
  237.             LD    V3, #4             ;    make start direction down
  238.             SNE   VB, #06            ;if last direction was right
  239.             LD    V3, #2             ;    make start direction left
  240.             SNE   VB, #05            ;if last direction was left
  241.             LD    V3, #0             ;    make start direction right
  242.             JP    SETUP
  243.  
  244. RANDSTART:  RND   V3, 7               ; Draw random starting box
  245.             ADD   V3, 1
  246.             RND   VC, #30
  247.             ADD   VC, #10
  248.             ADD   VC, V3              ; get random placement
  249.             RND   V3, 3
  250.             SHL   V3
  251.  
  252. SETUP:      LD    I, RANDDIR
  253.             ADD   I, V3               ; get random direction of opening
  254.             LD    V1, [I]
  255.             LD    VB, V0              ; starting flow direction
  256.             LD    V2, V1
  257.             LD    V9, V2              ; starting box type
  258.             LD    V0, VC
  259.             CALL  DRAWBOX
  260.             CALL  GETBOXTYPE          ; prevent change of starting box
  261.  
  262.             LD    VA, 2               ; set starting progression
  263.             CALL  DRAWRANDB
  264.  
  265.             LD    V7, 0               ; zero current job score
  266.             LD    V8, 0
  267.             CALL  WRITESCORE
  268.             CALL  WRITELEVEL
  269.             LD    V0, #FF             ; maximum delay of progression
  270.             LD    DT, V0              ;    for beginning of game
  271.  
  272. ; *** MAIN PROCEDURE FOR PLAYING GAME  ***
  273. GAMELOOP:
  274.             LD    V0, K_LEFT
  275.             SKNP  V0
  276.             CALL  MOVELEFT          ; move left if K_LEFT key pressed
  277.             LD    V0, K_RIGHT
  278.             SKNP  V0
  279.             CALL  MOVERIGHT         ; move right
  280.             LD    V0, K_UP
  281.             SKNP  V0
  282.             CALL  MOVEUP            ; move up
  283.             LD    V0, K_DOWN
  284.             SKNP  V0
  285.             CALL  MOVEDOWN          ; move down
  286.             LD    V0, K_PLACE
  287.             SKNP  V0
  288.             CALL  PLACEBOX          ; place box
  289.             LD    V0, K_UPLACE
  290.             SKNP  V0
  291.             CALL  UPLACEBOX       ; place box and use block shown for new
  292.             LD    V0, K_FAST
  293.             SKNP  V0
  294.             LD    VE, #02           ; go fast
  295.             LD    V0, DT
  296.             SNE   V0, 0
  297.             CALL  PROGRESS
  298.             JP    GAMELOOP
  299.  
  300. ; *****************************
  301. ; START OF SUBROUTINE CODE AREA
  302. ; *****************************
  303.  
  304. ; Places next box on a grid site if allowed and updates preview boxes
  305. ; V1 - V5 modified
  306. PLACEBOX:   LD    V0, #F            ; don't favor corners
  307.             CALL  GETRANDBLK        ; get next box type (V2) and update preview
  308.             LD    V0, VD            ; get pos to draw box
  309.             CALL  DRAWBOX           ; draw box (V2) at desired box coord
  310.             RET
  311.  
  312. ; Places next box on a grid site if allowed and updates preview boxes
  313. ; V1 - V5 modified
  314. UPLACEBOX:  CALL  NEWPREV           ; get next box type (V2) and update preview
  315.             LD    V0, VD            ; get pos to draw box
  316.             CALL  DRAWBOX           ; draw box (V2) at desired box coord
  317.             RET
  318.  
  319. ; Takes paddle coord in VD and put x coord in V0, y coord in V1
  320. ; V0 := (out) paddle x coord
  321. ; V1 := (out) paddle y coord
  322. ; VD := bott coord
  323. SPLITPOS:   LD    V0, VD
  324.             LD    V1, #0F
  325.             AND   V0, V1            ; store x part in V0
  326.             LD    V1, VD
  327.             SUB   V1, V0            ; store y part in V1
  328.             RET
  329.  
  330. ; The following 4 subroutines move the crosshair in the desired direction
  331. ; V0 := --- (m)
  332. ; V1 := --- (m)
  333. ; VD := paddle coord
  334. MOVELEFT:   CALL  DRAWBPADL      ;erase old paddle
  335.             CALL  DRAWCRSHR
  336.             CALL  SPLITPOS       ; calculate new pos
  337.             ADD   V0, #FF        ;  "
  338.             SNE   V0, #FF        ;  "
  339.             LD    V0, 0          ;  "
  340.             LD    VD, V1         ; save new pos
  341.             ADD   VD, V0
  342.             CALL  DRAWBPADL      ; draw new position
  343.             CALL  DRAWCRSHR
  344.             LD    V0, TYPERATE
  345.             CALL  PAUSE
  346.             RET
  347.  
  348. MOVERIGHT:  CALL  DRAWBPADL      ;erase old paddle
  349.             CALL  DRAWCRSHR
  350.             CALL  SPLITPOS       ; calculate new pos
  351.             ADD   V0, #01        ;  "
  352.             SNE   V0, #0A        ;  "
  353.             LD    V0, 9          ;  "
  354.             LD    VD, V1         ; save new pos
  355.             ADD   VD, V0
  356.             CALL  DRAWBPADL      ; draw new position
  357.             CALL  DRAWCRSHR
  358.             LD    V0, TYPERATE
  359.             CALL  PAUSE
  360. ;NORIGHT:    LD    V0, K_RIGHT    ; wait till key released
  361. ;            SKNP  V0
  362. ;            JP    NORIGHT
  363.             RET
  364.  
  365. MOVEUP:     CALL  DRAWSPADL      ;erase old paddle
  366.             CALL  DRAWCRSHR
  367.             CALL  SPLITPOS       ; calculate new pos
  368.             ADD   V1, #F0        ;  "
  369.             SNE   V1, #F0        ;  "
  370.             LD    V1, 0          ;  "
  371.             LD    VD, V1         ; save new pos
  372.             ADD   VD, V0
  373.             CALL  DRAWSPADL      ; draw new position
  374.             CALL  DRAWCRSHR
  375.             LD    V0, TYPERATE
  376.             CALL  PAUSE
  377.             RET
  378.  
  379. MOVEDOWN:   CALL  DRAWSPADL      ;erase old paddle
  380.             CALL  DRAWCRSHR
  381.             CALL  SPLITPOS       ; calculate new pos
  382.             ADD   V1, #10        ;  "
  383.             SNE   V1, #60        ;  "
  384.             LD    V1, #50        ;  "
  385.             LD    VD, V1         ; save new pos
  386.             ADD   VD, V0
  387.             CALL  DRAWSPADL      ; draw new position
  388.             CALL  DRAWCRSHR
  389.             LD    V0, TYPERATE
  390.             CALL  PAUSE
  391.             RET
  392.  
  393. ; Draw bottom paddle
  394. ; V0 := --- (m)
  395. ; V1 := --- (m)
  396. ; VD := paddle coord
  397. DRAWBPADL:  CALL  SPLITPOS       ; get paddle position
  398.             ADD   V0, #60
  399.             CALL  BOXTOSCR
  400.             LD    I, BOTTPADL    ; draw it
  401.             DRW   V0, V1, 4
  402.             RET
  403.  
  404. ; Draw side paddle
  405. ; V0 := --- (m)
  406. ; V1 := --- (m)
  407. ; VD := paddle coord
  408. DRAWSPADL:  CALL  SPLITPOS
  409.             LD    V0, V1
  410.             ADD   V0, #0A
  411.             CALL  BOXTOSCR
  412.             LD    I, SIDEPADL
  413.             DRW   V0, V1, 8
  414.             RET
  415.  
  416. ; Draw crosshair
  417. ; V0 := --- (m)
  418. ; V1 := --- (m)
  419. ; VD := paddle coord
  420. DRAWCRSHR:  LD    V0, VD
  421.             CALL  BOXTOSCR
  422.             LD    I, CROSSHAIR
  423.             DRW   V0, V1, 8
  424.             RET
  425.  
  426. ; All purpose pause subroutine
  427. ; V0 := (in) time to delay (m)
  428. PAUSE:      ADD   V0, #FF
  429.             SE    V0, 0
  430.             JP    PAUSE
  431.             RET
  432.  
  433. DRAWRANDB:  LD    I, RANDBLK
  434.             ADD   I, VA
  435.             LD    V0, [I]
  436.             CALL  GETBITADDR
  437.             LD    V0, 108
  438.             LD    V1, 28
  439.             DRW   V0, V1, 8
  440.             RET
  441.  
  442. ; Progress flow through current box
  443. ; V0 := --- (m)
  444. ; V1 := --- (m)
  445. ; V2 := --- (m)
  446. ; V3 := --- (m)
  447. ; V9 := current box type
  448. ; VA := box progression so far
  449. ; VB := flow direction
  450. ; VC := current box pos
  451.  
  452. PROGRESS:   CALL  DRAWRANDB
  453.             ADD   VA, 1
  454.  
  455.             LD    V0, V9       ; Get box type
  456.             LD    V1, #F0
  457.             AND   V0, V1       ; if box is a corner (type = #1X)
  458.             SNE   V0, 0        ;    then see if need to change direction
  459.             JP    KEEPDIR
  460.             SNE   VA, 4
  461.             JP    CORNERPROG
  462.             SNE   VA, 5
  463.             JP    ENDPROG
  464. KEEPDIR:    LD    V2, VA       ; store progression in v2
  465.             SE    VB, 0        ; invert progression if moving up
  466.             JP    NOINVERT     ;     ^- you will see why below (y position)
  467.             LD    V2, 8
  468.             SUB   V2, VA
  469. NOINVERT:   LD    V0, VB       ; store flow direction in v0
  470.             SHR   V0
  471.             SHR   V0
  472.             SE    V0, 0        ; if flowing right left, skip to R_L_PROG
  473.             JP    R_L_PROG
  474.             SE    VB, 0        ; if flowing down, subtract one from progression
  475.             ADD   V2, #FF      ;                     ^- graphical adjustment
  476.             LD    V0, VC       ; copy box coord to v0
  477.             CALL  BOXTOSCR     ; convert to screen coord, v0=x,v1=y
  478.             ADD   V1, V2       ; add progression to y coord for screen pos
  479.             LD    I, VERTMOVE  ; load address of vert moving flow
  480.             DRW   V0, V1, 1    ; draw vert moving flow
  481.             SNE   VF, 0        ; if collision took place
  482.             JP    SKIPIT       ;     check to make sure it
  483.             SE    VA, 1        ;    was only with crosshair
  484.             JP    SKIPIT       ;    so end of vertical flow
  485.             LD    V9, #00      ; else end the game
  486.             JP    ENDGAME
  487.  
  488. CORNERPROG: XOR   VB, V9       ; CHECK THIS OUT! Those value assignments
  489.             LD    V0, #07      ;    for box and direction aren't arbitrary
  490.             AND   VB, V0
  491.             LD    V0, VC
  492.             CALL  BOXTOSCR     ; get box coord
  493.             SE    V9, B_SE
  494.             JP    FCASE2       ; find proper bitmap to draw
  495.             LD    I, SEFLOW    ;   according to type of corner
  496.             ADD   V1, 4
  497. FCASE2:     SE    V9, B_NE
  498.             JP    FCASE3
  499.             LD    I, NEFLOW
  500.             ADD   V1, 2
  501. FCASE3:     SE    V9, B_SW
  502.             JP    FCASE4
  503.             LD    I, SWFLOW
  504.             ADD   V1, 4
  505. FCASE4:     SE    V9, B_NW
  506.             JP    FENDCASE
  507.             LD    I, NWFLOW
  508.             ADD   V1, 2
  509. FENDCASE:   DRW   V0, V1, 2    ; draw bitmap
  510.             JP    ENDPROG      ; end of corner flow
  511.  
  512. R_L_PROG:   SE    VB, 5        ; skip to right program if moving right
  513.             JP    RIGHTPRG
  514.             LD    V3, #80      ; start with 10000000 bitmap graphic
  515. LEFTPRG:    SNE   V2, 8        ; iterate over progressions left
  516.             JP    R_L_DRAW
  517.             SHR   V3           ; build proper sprite by shifting 1 digit right
  518.             ADD   V2, 1        ;    for each progression not obtained
  519.             JP    LEFTPRG      ; end of left flow
  520. RIGHTPRG:   LD    V3, #01      ; start with 00000001
  521. RIGHTPRG2:  SNE   V2, 8        ; iterate over progressions left
  522.             JP    R_L_DRAW
  523.             SHL   V3           ; build proper sprite
  524.             ADD   V2, 1
  525.             JP    RIGHTPRG2    ; end of right flow
  526. R_L_DRAW:   LD    V1, V3
  527.             LD    V0, V3
  528.             LD    I, TEMP
  529.             LD    [I], V1      ; store built sprite doubled in memory
  530.             LD    I, TEMP
  531.             LD    V0, VC
  532.             CALL  BOXTOSCR     ; get position of box to progress flow
  533.             ADD   V1, 3
  534.             SE    V9, B_CROS   ; "tunnel under" if a crossbar and on 4,5 progr
  535.             JP    DRAWIT       ;    else draw the progression
  536.             SNE   VA, 4
  537.             JP    NODRAW
  538.             SE    VA, 5
  539. DRAWIT:     DRW   V0, V1, 2    ; write sprite to screen
  540. NODRAW:     SNE   VF, 0        ; if collision took place
  541.             JP    SKIPIT       ;     check to make sure it
  542.             SE    VA, 1        ;     was only with crosshair
  543.             JP    SKIPIT       ;     so end of horizontal flow
  544.             LD    V9, #00      ; else end the game
  545.             JP    ENDGAME      ;
  546. SKIPIT:     SE    VA, 8        ; if at end of progression through box
  547.             JP    ENDPROG
  548.             CALL  WRITESCORE
  549.             LD    V0, 0
  550. SCOREIT:    ADD   V7, 1         ; earn 3 points for each box passed
  551.             SE    V7, 100
  552.             JP    SCOREIT2
  553.             ADD   V8, 1
  554.             LD    V7, 0
  555. SCOREIT2:   ADD   V0, 1
  556.             SE    V0, 3
  557.             JP    SCOREIT
  558.             CALL  WRITESCORE
  559.             LD    VA, 0
  560.             CALL  GETNEXTBOX     ; get next box pos and type
  561. ENDPROG:    LD    V0, VE        ; resest timer for next progress check
  562.             LD    V1, V8
  563.             ADD   V1, V7
  564.             SNE   V1, 0
  565.             ADD   V0, #B0       ; increase timer if only starting
  566.             LD    DT, V0
  567.             CALL  DRAWRANDB
  568.             RET
  569.  
  570. ; Wait until space key is pressed
  571. ; V0 := --- (m)
  572. WAIT:       LD    V0, #B
  573. WAIT2:      SKP   V0            ; wait till press space
  574.             JP    WAIT2
  575. WAIT3:      SKNP  V0
  576.             JP    WAIT3         ; wait till space key released
  577.             RET
  578.  
  579. ; Determine if game ends, tally score, and reset for next screen
  580. ; Changes everything
  581. ENDGAME:    LD    V0, #3
  582.             LD    ST, V0        ; BEEP
  583.             CALL  WAIT
  584.             CLS
  585.             LD    V2, 0
  586.             LD    V3, 0
  587. CHECKBONUS: LD    I, BOXINFO    ; iterate through box grid array
  588.             ADD   I, V2         ;    adding together field
  589.             LD    V1, [I]       ;    that has a 1 if flowed through
  590.             ADD   V2, 2
  591.             ADD   V3, V1
  592.             SE    V2, 120
  593.             JP    CHECKBONUS    ; if every box flowed through
  594.             SNE   V3, 60        ;    then give a bonus 100 points
  595.             ADD   V8, 1
  596.  
  597.             LD    I, TSCORE     ; get old stored total score
  598.             LD    V1, [I]
  599.             ADD   V0, V7        ; add new score to total
  600.             LD    V3, 100
  601.             SUB   V0, V3
  602.             LD    V4, VF
  603.             SE    V4, 0         ; if over 100
  604.             ADD   V1, 1         ;     increment hundreds digit
  605.             SE    V4, 1         ; else
  606.             ADD   V0, 100       ;     put back to normal
  607.             ADD   V1, V8
  608.             LD    I, TSCORE     ; save new total
  609.             LD    [I], V1
  610.  
  611.             LD    V5, V0        ; store tens & ones digit
  612.             LD    V3, 40        ; x coord to display total
  613.             LD    V4, 40        ; y coord to display total
  614.             LD    I, SCORE      ; STORE BCD
  615.             LD    B, V1         ;     of hundreds score to  memory
  616.             LD    V2, [I]       ; read BCD
  617.             DB    #F0, #30      ; point to sprite of ten thousands digit
  618.             DRW   V3, V4, 10
  619.             ADD   V3, 11
  620.             DB    #F1, #30      ; point to sprite of thousands digit
  621.             DRW   V3, V4, 10
  622.             ADD   V3, 11
  623.             DB    #F2, #30      ; point to sprite of hundreds digit
  624.             DRW   V3, V4, 10
  625.             LD    I, SCORE      ; STORE BCD
  626.             LD    B, V5         ;     of tens & ones score to memory
  627.             LD    V2, [I]       ; read BCD
  628.             ADD   V3, 11
  629.             DB    #F1, #30      ; point to sprite of tens digit
  630.             DRW   V3, V4, 10
  631.             ADD   V3, 11
  632.             DB    #F2, #30      ; point to sprite of ones digit
  633.             DRW   V3, V4, 10
  634.  
  635.             CALL  WRITESCORE    ; write score of last job in corner
  636.             LD    I, LEVEL
  637.             LD    V0, [I]
  638.             LD    VE, V0        ; get stored level in case FAST used
  639.             SNE   VE, #02       ; don't go beyond level 10
  640.             ADD   VE, #04
  641.             ADD   VE, #FC       ; make level harder
  642.  
  643.             SE    V8, 0
  644.             JP    GOODSCORE     ; check if score good enough to continue
  645.             SHR   V0            ; need 100 - (41 - 2 * LEVEL) pts
  646.             LD    V1, 100       ;     in order to continue
  647.             SUB   V1, V0        ;     LVL 1 -> 61
  648.             SUB   V7, V1        ;     LVL 2 -> 63
  649.             SNE   VF, 0         ;     LVL 3 -> 65, and so on
  650.             JP    GAMEOVER      ; if not, gameover
  651. GOODSCORE:  CALL  DROPWAIT      ; show the dripping graphic and wait
  652.             SE    V0, #0        ; if pause game key (.) not pressed
  653.             JP    START         ; go to next job
  654.             LD    V3, #1        ; signal flag that game is to continue
  655.             JP    PAUSEGAME
  656.  
  657. GAMEOVER:   LD    I, HDOVER     ; print 'OVER' on screen
  658.             LD    V0, 42
  659.             LD    V1, 24
  660.             DRW   V0, V1, 5
  661.             ADD   V0, 8
  662.             LD    V2, 5
  663.             ADD   I, V2
  664.             DRW   V0, V1, 5
  665.             CALL  DROPWAIT      ; show the dripping graphic and wait
  666.             LD    V3, #0        ; signal that game not to be resumed
  667. PAUSEGAME:  LD    I, TSCORE     ; get old stored total score
  668.             LD    V1, [I]
  669.             LD    V2, VE
  670.             DB    #F3, #75      ; store total score in user flags
  671.             LD    V0, #B
  672. NOSPCPRESS: SKNP  V0
  673.             JP    NOSPCPRESS
  674.             LD    V0, #0
  675. NOPERPRESS: SKNP  V0
  676.             JP    NOPERPRESS
  677.             DB    #00, #FD      ; exit game
  678.  
  679. ; Wait with drop graphic
  680. ; V0 := --- (m)
  681. ; V1 := --- (m)
  682. ; V2 := --- (m)
  683. ; V3 := --- (m)
  684. ; V4 := --- (m)
  685. DROPWAIT:   LD    I, HORZBOX          ; draw faucet type pipe
  686.             LD    V3, 2
  687.             LD    V4, 8
  688.             DRW   V3, V4, 8
  689.             LD    I, SWBOX
  690.             LD    V3, 10
  691.             DRW   V3, V4, 8
  692.             LD    I, DROP             ; draw drop and animate
  693. DROPIT:     LD    V3, 14
  694.             LD    V4, 16
  695.             DRW   V3, V4, 7
  696. DRAWDROP:   LD    V0, #25
  697.             CALL  PAUSE
  698.             LD    V0, #B
  699.             SKNP  V0
  700.             JP    ENDDROP
  701.             LD    V0, #0
  702.             SKNP  V0
  703.             JP    ENDDROP
  704.             DRW   V3, V4, 7
  705.             ADD   V4, 2
  706.             SNE   V4, 56
  707.             JP    DROPIT
  708.             DRW   V3, V4, 7
  709.             JP    DRAWDROP
  710. ENDDROP:    RET
  711.  
  712. ; Get screen coord from box coord
  713. ;   V0 := (in) box coord, (out) screen x
  714. ;   V1 :=                 (out) screen y
  715. BOXTOSCR:   LD    V1, V0
  716.             LD    VF, #F0
  717.             AND   V1, VF
  718.             SHR   V1           ; get y part of box coord
  719.             LD    VF, #0F
  720.             AND   V0, VF       ; get x part of box coord
  721.             SHL   V0           ; multipy box coords by 8
  722.             SHL   V0
  723.             SHL   V0
  724.             ADD   V0, 16       ; add proper offsets to get screen coord
  725.             ADD   V1, 2
  726.             RET
  727.  
  728. ; Get box coord from screen coord
  729. ;   V0 := (in) screen x, (out) box coord
  730. ;   V1 := (in) screen y, (m)
  731. SCRTOBOX:   ADD   V0, #F0      ; substr proper offsets
  732.             ADD   V1, #FE
  733.             SHR   V0           ; divide screen coords by 8
  734.             SHR   V0
  735.             SHR   V0
  736.             SHL   V1
  737.             ADD   V0, V1       ; put together into one register
  738.             RET
  739.  
  740. ; Get grid array addr from box coord
  741. ;   V0 := (in) box coord  (m)
  742. ;   V1 :=                 (m)
  743. ;   I  := addr
  744. BOXTOADDR:  LD    I, BOXINFO   ; set address to beginning of box array
  745.             LD    V1, V0
  746.             LD    VF, #0F
  747.             AND   V1, VF
  748.             SHL   V1
  749.             ADD   I, V1        ; add x offset (2 * box x)
  750.             LD    VF, #F0
  751.             AND   V0, VF
  752.             SHR   V0
  753.             LD    V1, V0
  754.             SHR   V1
  755.             SHR   V1
  756.             ADD   V0, V1
  757.             SHL   V0
  758.             ADD   I, V0        ; add y offset (20 * box y)
  759.             RET
  760.  
  761. ; Draws a box on the grid if possible. if not, penalize
  762. ;   V0 := box coord (m)
  763. ;   V1 :=   ---     (m)
  764. ;   V2 := box type  (m)
  765. ;   V3 :=   ---     (m)
  766. ;   V4 :=   ---     (m)
  767. ;   V5 :=   ---     (m)
  768. DRAWBOX:    LD    V3, V0           ; push box coord
  769.             CALL  BOXTOADDR        ; set I to array address
  770.             LD    V1, [I]          ; read in current box
  771.             LD    V5, 0
  772.             SE    V0, #0B          ; if box already placed there,
  773.             LD    V5, #FF          ;     then penalty
  774.             SNE   V1, 00           ; if box full
  775.             JP    DRAWBOX2
  776.             LD    V1, #3           ;   then disallow
  777.             LD    ST, V1           ;   and beep
  778.             JP    SKIPDRAW
  779. DRAWBOX2:   CALL  GETBITADDR       ; get mask addr for current box
  780.             LD    V0, V3           ; pop box coord
  781.             CALL  BOXTOSCR         ; convert to scr coord
  782.             DRW   V0, V1, 8        ; erase current box
  783.             LD    V0, V3           ; pop box coord
  784.             CALL  BOXTOADDR        ; set I to array address
  785.             LD    V1, 0
  786.             LD    V0, V2
  787.             LD    [I], V1          ; write box type to array
  788.             LD    V0, V2
  789.             CALL  GETBITADDR       ; get mask addr for box
  790.             LD    V0, V3           ; pop box coord
  791.             CALL  BOXTOSCR         ; get screen coord
  792.             DRW   V0, V1, 8        ; draw desired box
  793. SKIPDRAW:   CALL  WRITESCORE
  794.             ADD   V7, V5           ; substract penalty
  795.             SE    V7, #FF          ; if V7 was not 0
  796.             JP    NOADJUST         ;     no adjustment needed
  797.             SNE   V8, 0            ; else if V8 is 0
  798.             JP    ZEROOUT          ;          set job score to 0
  799.             ADD   V8, #FF          ;      else substract 100
  800.             LD    V7, 99           ;           and add 99
  801.             JP    NOADJUST
  802. ZEROOUT     LD    V7, 0
  803. NOADJUST:   CALL  WRITESCORE
  804.             RET
  805.  
  806. ; Gets bitmap address for box type
  807. ; V0 := box type
  808. ; V1 := --- (m)
  809. GETBITADDR: LD    V1, #0F
  810.             AND   V0, V1           ; get offset to mask for box
  811.             SHL   V0
  812.             SHL   V0
  813.             SHL   V0
  814.             LD    I, ZEROBOX       ; set I to mask address
  815.             ADD   I, V0            ; add offset
  816.             RET
  817.  
  818.  
  819. ; Get box type from storage array and mark it as unchangable
  820. ; V0 := (m)
  821. ; V1 := (m)
  822. ; V3 := (in) box pos
  823. ; VC := (in) box pos
  824. ; V9 := (out) box type
  825. GETBOXTYPE: LD    V0, VC             ; get array addr from box pos
  826.             CALL  BOXTOADDR
  827.             LD    V1, [I]            ; read boxtype
  828.             SNE   V0, #0B
  829.             JP    ENDGAME
  830.             LD    V9, V0
  831.             LD    V0, VC
  832.             CALL  BOXTOADDR          ; prevent change of box
  833.             LD    V0, V9
  834.             LD    V1, #01
  835.             LD    [I], V1
  836.             RET
  837.  
  838. ; Get box coord for next box depending on direction from last
  839. ; V0 := --- (m)
  840. ; V1 := --- (m)
  841. ; V2 := --- (m)
  842. ; VB := direction of flow
  843. ; VC := (in) curr box coord, (out) next box coord
  844. GETNEXTBOX: LD    V3, #00
  845.             SNE   VB, F_RIGHT
  846.             LD    V3, #01      ; if right, add one to x
  847.             SNE   VB, F_DOWN
  848.             LD    V3, #10      ; if down, add one to y
  849.             SNE   VB, F_UP
  850.             LD    V3, #F0      ; if up, substract 1 from y
  851.             SNE   VB, F_LEFT
  852.             LD    V3, #FF      ; if left, subtract 1 from x
  853.             LD    V1, VC
  854.             ADD   V1, V3       ; adjust
  855.             LD    VF, #F0
  856.             AND   V1, VF
  857.             SNE   V1, #F0      ; if gone off top
  858.             JP    ENDGAME
  859.             SNE   V1, #60      ; if gone off bottom
  860.             JP    ENDGAME
  861.             LD    V1, VC
  862.             ADD   V1, V3
  863.             LD    VF, #0F
  864.             AND   V1, VF
  865.             SNE   V1, #0F      ; if gone off left
  866.             JP    ENDGAME
  867.             SNE   V1, #0A      ; if gone off right
  868.             JP    ENDGAME
  869.             ADD   VC, V3
  870.             CALL  GETBOXTYPE
  871.             RET
  872.  
  873. ; Get a new preview box and update list
  874. ; V0 := --- (m)
  875. ; V1 := --- (m)
  876. ; V2 := --- (m) , (out) box type dropped
  877. ; V3 := --- (m)
  878. ; V4 := --- (m)
  879. ; V5 := --- (m)
  880. NEWPREV:    LD    V1, VA
  881.             JP    GOTIT
  882. GETRANDBLK: RND   V1, 7               ; randomly determine new box
  883.             SHR   V0
  884.             SHR   V0
  885.             SNE   V0, 0               ; if favoring corners (V0 = 0,1,2,3)
  886.             SHR   V1                  ;   divide offset by 2
  887. GOTIT:      LD    I, RANDBLK
  888.             ADD   I, V1
  889.             LD    V0, [I]
  890.             LD    V5, V0              ; store new box type in V5
  891.             LD    V4, 3               ; top preview box coord
  892.             LD    V3, 0
  893. NEXTPREV:   LD    I, PBOXINFO         ; shift old box graphics down
  894.             ADD   I, V3
  895.             LD    V0, [I]
  896.             LD    V2, V0
  897.             CALL  GETBITADDR                 ; erase old box graphic
  898.             LD    V0, 4
  899.             DRW   V0, V4, 8
  900.             LD    I, PBOXINFO
  901.             ADD   I, V3
  902.             LD    V0, V5
  903.             LD    [I], V0
  904.             CALL  GETBITADDR                 ; draw new box graphic
  905.             LD    V0, 4
  906.             DRW   V0, V4, 8
  907.             ADD   V4, 12
  908.             LD    V5, V2
  909.             ADD   V3, 1
  910.             SE    V3, 5
  911.             JP    NEXTPREV
  912.             RET
  913.  
  914. ; Write the score to screen
  915. ; V0 := --- (m)
  916. ; V1 := --- (m)
  917. ; V2 := --- (m)
  918. ; V3 := --- (m)
  919. ; V4 := --- (m)
  920. ; V7 := (in) score
  921. WRITESCORE: LD    V3, 105                ; x pos
  922.             LD    V4, 9                  ; y pos
  923.             LD    I, SCORE               ; write BCD
  924.             LD    B, V8                  ;     of hundred score to memory
  925.             LD    V2, [I]                ; read BCD
  926.             LD    F, V2                  ; point to sprite of hundreds digit
  927.             DRW   V3, V4, 5
  928.             ADD   V3, 6
  929.             LD    I, SCORE               ; write BCD
  930.             LD    B, V7                  ;     of tens and ones score to memory
  931.             LD    V2, [I]                ; read BCD
  932.             LD    F, V1                  ; point to sprite of tens digit
  933.             DRW   V3, V4, 5
  934.             ADD   V3, 6
  935.             LD    F, V2                  ; point to sprite of ones digit
  936.             DRW   V3, V4, 5
  937.             RET
  938.  
  939. ; Write the level to screen
  940. ; V0 := --- (m)
  941. ; V1 := --- (m)
  942. ; V2 := --- (m)
  943. ; V3 := --- (m)
  944. ; V4 := --- (m)
  945. ; VE := (in) level
  946. WRITELEVEL: LD    V0, VE                 ; convert speed to game level
  947.             ADD   V0, #FE
  948.             SHR   V0
  949.             SHR   V0
  950.             LD    V1, 20
  951.             SUB   V1, V0
  952.             LD    I, SCORE               ; write BCD
  953.             LD    B, V1                  ;     of level to memory
  954.             LD    V2, [I]                ; read BCD
  955.             DB    #F1, #30               ; point to sprite of tens digit
  956.             LD    V3, 104
  957.             LD    V4, 50
  958.             DRW   V3, V4, 10
  959.             ADD   V3, 11
  960.             DB    #F2, #30               ; point to sprite of ones digit
  961.             DRW   V3, V4, 10
  962.             RET
  963.  
  964. ; ******************
  965. ; START OF DATA AREA
  966. ; ******************
  967.  
  968. RBORDER:    DW    #F8F8
  969.  
  970. PRV1BOX:    DW    #C0C0, #C0C0, #C0C0, #C0C0, #C0C0, #C0FF
  971.  
  972. PRV2BOX:    DW    #0303, #0303, #0303, #0303, #0303, #03FF
  973.  
  974. LEVEL:      DW    #0000
  975.  
  976. ZEROBOX:    DW    #0000, #0000, #0000, #0000   ;0  blank box
  977.  
  978. VERTBOX:    DW    #C3C3, #C3C3, #C3C3, #C3C3   ;1  vertical pipe
  979.  
  980. HORZBOX:    DW    #FFFF, #0000, #0000, #FFFF   ;2  horizontal pipe
  981.  
  982. CROSBOX:    DW    #C3C3, #0000, #0000, #C3C3   ;3  crossing pipes
  983.  
  984. FULLBOX:    DW    #FFFF, #FFFF, #FFFF, #FFFF   ;4  full box
  985.  
  986. SWBOX:      DW    #FFFF, #0F07, #0303, #83C3   ;5  south to west pipe
  987.  
  988. SEBOX:      DW    #FFFF, #F0E0, #C0C0, #C1C3   ;6  south to east pipe
  989.  
  990. ESTRBOX:    DW    #FFFF, #C0C0, #C0C0, #FFFF   ;7  east open start pipe
  991.  
  992. WSTRBOX:    DW    #FFFF, #0303, #0303, #FFFF   ;8  west open start pipe
  993.  
  994. NSTRBOX:    DW    #C3C3, #C3C3, #C3C3, #FFFF   ;9  north open start pipe
  995.  
  996. SSTRBOX:    DW    #FFFF, #C3C3, #C3C3, #C3C3   ;A  south open start pipe
  997.  
  998. GRID:       DW    #007E, #4242, #4242, #7E00   ;11 (B) empty grid site
  999.  
  1000. TEMP:       DW    #0000, #0000, #0000, #0000   ;12 (C) temp memory area
  1001.  
  1002. NEBOX:      DW    #C3C1, #C0C0, #E0F0, #FFFF   ;13 (D) north to east pipe
  1003.  
  1004. NWBOX:      DW    #C383, #0303, #070F, #FFFF   ;14 (E) north to west pipe
  1005.  
  1006. CROSSHAIR:  DW    #0000, #183C, #3C18, #0000   ;15 (F)
  1007.  
  1008. SIDEPADL:   DW    #0010, #1070, #7010, #1000
  1009.  
  1010. BOTTPADL:   DW    #0018, #187E
  1011.  
  1012. VERTMOVE:   DW    #1800                        ; bitmap of vertical flow
  1013.  
  1014. SEFLOW:     DW    #0804
  1015. NEFLOW:     DW    #0408
  1016. SWFLOW:     DW    #1020
  1017. NWFLOW      DW    #2010
  1018.  
  1019. RANDBLK:    DW    #1D15, #161E, #0102, #0303   ; used for random block select
  1020.  
  1021. RANDDIR:    DW    #0607, #0508, #0009, #030A   ; used for random direction
  1022.  
  1023. PBOXINFO:   DW    #0000, #0000, #0000          ; preview box info
  1024.  
  1025. SCORE:      DW    #0000, #0000                 ; total score storage
  1026. TSCORE:     DW    #0000, #0000                 ; temp score area
  1027.  
  1028. TITLE:      DW    #A3A2, #E3A2, #AABB, #9293, #123A
  1029. TITLE2:     DW    #BBA2, #B322, #3A88, #8888, #4048
  1030. HDSCORE:    DW    #D992, #D252, #D93B, #AAB3, #AA2B
  1031. HDLEVEL:    DW    #9A92, #9A91, #D9B4, #A4B4, #2436
  1032. HDOVER:     DW    #EAAA, #AEA4, #E4EE, #8ACE, #89E9
  1033. DROP:       DW    #2020, #70F8, #F8F8, #7000
  1034.  
  1035. BOXINFO:    DW    #0B00, #0B00, #0B00, #0B00, #0B00  ; 60x2 array for
  1036. X1:         DW    #0B00, #0B00, #0B00, #0B00, #0B00  ; storage of grid
  1037. X2:         DW    #0B00, #0B00, #0B00, #0B00, #0B00  ; placements and
  1038. X3:         DW    #0B00, #0B00, #0B00, #0B00, #0B00  ; flow control
  1039. X4:         DW    #0B00, #0B00, #0B00, #0B00, #0B00
  1040. X5:         DW    #0B00, #0B00, #0B00, #0B00, #0B00
  1041. X6:         DW    #0B00, #0B00, #0B00, #0B00, #0B00
  1042. X7:         DW    #0B00, #0B00, #0B00, #0B00, #0B00
  1043. X8:         DW    #0B00, #0B00, #0B00, #0B00, #0B00
  1044. X9:         DW    #0B00, #0B00, #0B00, #0B00, #0B00
  1045. X10:        DW    #0B00, #0B00, #0B00, #0B00, #0B00
  1046. X11:        DW    #0B00, #0B00, #0B00, #0B00, #0B00
  1047. -- 
  1048. Paul Raines
  1049. Georgia Institute of Technology, Atlanta Georgia, 30332
  1050. uucp:      ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!vapsppr
  1051. Internet: vapsppr@prism.gatech.edu
  1052.